import {
  RouteOptionsType,
  RouteTargetType,
  RouterRegOptionType,
} from "../types";

/**方法装饰器key标识-路由请求 */
export const METHOD_KEY_ROUTE = "decorator_method:route";

/**
 * 定义路由请求
 *
 * @param {RouteOptionsType} routerOptions 路由参数
 * @example
 * ```javascript
 * +@RequestMapping({ method: "get" })
 * +async fnRequestMapping(ctx: any) {
 * +  return { msg: "ok", data: ctx.data };
 * +}
 * ```
 */
export function RequestMapping(
  routerOptions: RouteOptionsType
): (target: any, handlerKey: any) => void {
  // 默认空字符串，拼接控制器上/前缀
  if (!routerOptions.path) {
    routerOptions.path = "";
  }
  // 初始可用中间件
  if (!Array.isArray(routerOptions.middleware)) {
    routerOptions.middleware = [];
  }
  if (typeof routerOptions.ignoreGlobalPrefix !== "boolean") {
    routerOptions.ignoreGlobalPrefix = false;
  }
  return (target: any, handlerKey: any) => {
    // 定义标识到原型链
    let routes: RouteTargetType[] = Reflect.get(target, METHOD_KEY_ROUTE);
    if (!Array.isArray(routes)) {
      routes = [];
    }
    // 取得句柄函数
    const handle: RouteTargetType["handle"] = Reflect.get(target, handlerKey);
    // 加入到原型链标识
    routes.push({ ...routerOptions, handle });
    Reflect.set(target, METHOD_KEY_ROUTE, routes);
  };
}

/**
 * GET 路由请求
 *
 * @param {String} path 路由地址
 * @param {RouterRegOptionType} routerOptions 路由参数
 * @example
 * ```javascript
 * +@Get("/get")
 * +async fnGet(ctx: any) {
 * +  return { msg: "ok", data: ctx };
 * +}
 * ```
 */
export function Get(
  path?: string,
  routerOptions?: RouterRegOptionType
): (target: any, handlerKey: any) => void {
  return RequestMapping({ method: "get", path, ...routerOptions });
}

/**
 * POST 路由请求
 *
 * @param {String} path 路由地址
 * @param {RouterRegOptionType} routerOptions 路由参数
 * @example
 * ```javascript
 * +@Post("/post")
 * +async fnPost(ctx: any) {
 * +  return { msg: "ok", data: ctx };
 * +}
 * ```
 */
export function Post(
  path?: string,
  routerOptions?: RouterRegOptionType
): (target: any, handlerKey: any) => void {
  return RequestMapping({ method: "post", path, ...routerOptions });
}

/**
 * PUT 路由请求
 *
 * @param {String} path 路由地址
 * @param {RouterRegOptionType} routerOptions 路由参数
 * @example
 * ```javascript
 * +@Put("/put")
 * +async fnPut(ctx: any) {
 * +  return { msg: "ok", data: ctx };
 * +}
 * ```
 */
export function Put(
  path?: string,
  routerOptions?: RouterRegOptionType
): (target: any, handlerKey: any) => void {
  return RequestMapping({ method: "put", path, ...routerOptions });
}

/**
 * DELETE 路由请求
 *
 * @param {String} path 路由地址
 * @param {RouterRegOptionType} routerOptions 路由参数
 * @example
 * ```javascript
 * +@Del("/del")
 * +async fnDel(ctx: any) {
 * +  return { msg: "ok", data: ctx };
 * +}
 * ```
 */
export function Del(
  path?: string,
  routerOptions?: RouterRegOptionType
): (target: any, handlerKey: any) => void {
  return RequestMapping({ method: "delete", path, ...routerOptions });
}
